#ifndef _GAME_COMMAND_H_
#define _GAME_COMMAND_H_

#include <string>
#include <vector>

using namespace std;

const int MAX_SERIALIZED_GAME_COMMAND_LEN = 64;		// Should be a multiple of word size

// Note: Do not introduce a vtable into this struct. We must be able to recvfrom into it directly.
struct SerializedGameCommand
{
	char data[MAX_SERIALIZED_GAME_COMMAND_LEN];
};

/*	----------------------------------------------------------------------------------------------------------------------
	Commands				Parameters					Description
	----------------------------------------------------------------------------------------------------------------------
	GAME_INIT				seed						Game initialized with the provided seed
	GAME_LENGTHENFRAME
	
	UNIT_MOVE 				unit1 (x,y)					unit1 begins moving to position (x,y)
	
	UNIT_STOP				unit1						unit1 stops (makes its action neutural)
	UNIT_ATTACK 			unit1 unit2					unit1 begins attacking unit2
	UNIT_GATHER 			unit1 resource1				unit1 begins gathering resource1
	UNIT_BUILD				unit1 buildingtype1 (x,y)	unit1 begins building buildingtype1 at position (x,y)
	
	BUILDING_PRODUCE 		building1 unittype1			building1 queues production of unittype1
	BUILDING_STOP			building1					building1 cancels production of the current unit it's building
*/

struct GameCommand
{
	unsigned long timestamp;						// The time at which this command should be executed
	
	GameCommand() : timestamp(0)	{	}
	virtual ~GameCommand()	{}
	
	bool operator<(const GameCommand &c) const {	// Required by Game's command_queue (a priority queue) for sorting
		return this->timestamp > c.timestamp;
	}
	
	virtual void onExecute() = 0;
	virtual string toString() = 0;
	virtual SerializedGameCommand serialize() const = 0;
	
	static GameCommand* interpret(const SerializedGameCommand&);
	static GameCommand* interpret(const char* line);
	
private:
	GameCommand(const GameCommand&);
	GameCommand& operator=(const GameCommand&);

};

struct GameCommandPointerLessThan {
	bool operator()(GameCommand* a, GameCommand* b) const;
};

#endif
